#pragma once
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <queue>
#include <mutex>
#include <string>
#include <functional>
#include <time.h>
using namespace std;
template <class T>
class Myqueue
{
public:
    Myqueue(int capacity = 5)
        : _capacity(capacity)
    {
        pthread_cond_init(&_full, nullptr);
        pthread_cond_init(&_empty, nullptr);
        pthread_mutex_init(&_mtx, nullptr);
    }
    void push(const T &val)
    {
        // 加锁
        pthread_mutex_lock(&_mtx);
        // 访问临界资源
        while (_q.size() == static_cast<size_t>(_capacity))
        {
            pthread_cond_signal(&_empty);
            pthread_cond_wait(&_full, &_mtx);
            //pthread_cond_signal(&_empty);
        }
        _q.push(val);
        cout << "生产者插入数据成功" << endl;
        // 解锁
        pthread_mutex_unlock(&_mtx);
    }
    void pop(T &x)
    {
        pthread_mutex_lock(&_mtx);
        while (_q.size() == 0)
        {
            pthread_cond_signal(&_full);
            pthread_cond_wait(&_empty, &_mtx);
            //pthread_cond_signal(&_full);
        }
        x = _q.front();
        _q.pop();
        cout << "消费者取数据" << endl;
        pthread_mutex_unlock(&_mtx);
    }
    ~Myqueue()
    {
        _capacity = 0;
        pthread_cond_destroy(&_full);
        pthread_cond_destroy(&_empty);
        pthread_mutex_destroy(&_mtx);
    }

private:
    queue<T> _q;
    int _capacity;
    pthread_mutex_t _mtx;
    pthread_cond_t _full;
    pthread_cond_t _empty;
};